<template>
  <div class="container" style="padding: 20px">
    <el-row :gutter="20">
      <!-- 账户列表 -->
      <el-col :span="12">
        <el-card shadow="hover">
          <div slot="header" class="clearfix">
            <span>主账户列表</span>
            <el-button type="primary" size="small" :loading="loading.accounts" @click="getAccounts" style="float: right;">刷新账户</el-button>
          </div>

          <el-table :data="accounts" border v-loading="loading.accounts" empty-text="未检测到账户">
            <el-table-column type="index" align="center" width="80" label="序号" />
            <el-table-column align="center" label="账户地址" min-width="300" >
              <template slot-scope="{ row }">
                <el-tooltip :content="row.address" placement="top">
<!--                  <span class="address-text"> {{ formatAddress(row.address) }} </span>-->
                  <span class="address-text"> {{ row.address}} </span>
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>

      <!-- 区块信息 -->
      <el-col :span="12">
        <el-card shadow="hover">
          <div slot="header" class="clearfix">
            <span>区块链状态</span>
            <el-button type="success" size="small" :loading="loading.block" @click="refreshBlockData" style="float: right;">刷新数据</el-button>
          </div>

          <div class="block-info">
            <div class="info-item">
              <label>当前区块高度：</label>
              <el-tag type="info">{{ blockNumber.toLocaleString() }}</el-tag>
            </div>

            <div class="info-item">
              <label>Gas价格：</label>
              <el-tag type="warning">{{ formatGasPrice(gasPrice) }} Gwei</el-tag>
            </div>

            <div class="info-item">
              <label>节点状态：</label>
              <el-tag :type="nodeStatus ? 'success' : 'danger'">{{ nodeStatus ? '已连接' : '未连接' }}</el-tag>
            </div>
          </div>
        </el-card>

        <el-card shadow="hover">
          <div slot="header" class="clearfix">
            <span>全网交易统计</span>
            <el-button type="warning" size="small" :loading="loading.totalTx" @click="getTotalTransactions" style="float: right;">刷新统计</el-button>
          </div>
          <div class="total-tx">
            累计交易总数：<el-tag type="danger">{{ totalTransactions.toLocaleString() }}</el-tag>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import Web3 from 'web3';

export default {
  data() {
    return {
      web3: null,
      accounts: [],
      blockNumber: 0,
      gasPrice: 0,
      nodeStatus: false,
      totalTransactions: 0, //全网交易次数
      loading: {
        accounts: true,
        block: true,
        totalTx: false
      },
      autoUpdate: null
    };
  },

  methods: {
    // 初始化Web3
    async initWeb3() {
      try {
        if (!process.env.VUE_APP_WEB3_API) {
          throw new Error('未检测到区块链节点配置，请检查环境变量');
        }

        this.web3 = new Web3(process.env.VUE_APP_WEB3_API);
        await this.checkNodeConnection();
        await Promise.all([this.getAccounts(), this.getBlockData(), this.getTotalTransactions()]);

      } catch (error) {
        this.$message.error(`初始化失败: ${error.message}`);
        console.error('Web3初始化错误:', error);
      }
    },
    // 获取全网交易总数（遍历区块）
    async getTotalTransactions() {
      this.loading.totalTx = true;
      try {
        const latestBlock = await this.web3.eth.getBlockNumber();
        let total = 0;

        // 批量获取区块（每次获取10个提高效率）
        const batchSize = 10;
        for (let i = 0; i <= latestBlock; i += batchSize) {
          const requests = [];
          const end = Math.min(i + batchSize, latestBlock);

          for (let j = i; j <= end; j++) {
            requests.push(this.web3.eth.getBlock(j, true));
          }

          const blocks = await Promise.all(requests);
          total += blocks.reduce((sum, block) => sum + block.transactions.length, 0);
        }

        this.totalTransactions = total;
      } catch (error) {
        this.$message.error('统计失败: ' + error.message);
        console.error('交易统计错误:', error);
      } finally {
        this.loading.totalTx = false;
      }
    },

    // 检查节点连接
    async checkNodeConnection() {
      try {
        const isListening = await this.web3.eth.net.isListening();
        this.nodeStatus = isListening;
        return isListening;
      } catch (error) {
        this.nodeStatus = false;
        throw error;
      }
    },

    // 获取账户列表
    async getAccounts() {
      this.loading.accounts = true;
      try {
        const accounts = await this.web3.eth.getAccounts();
        this.accounts = accounts.map(address => ({ address }));
      } catch (error) {
        this.$message.error('获取账户失败: ' + error.message);
        console.error('账户获取错误:', error);
      } finally {
        this.loading.accounts = false;
      }
    },

    // 获取区块数据
    async getBlockData() {
      this.loading.block = true;
      try {
        const [blockNumber, gasPrice] = await Promise.all([
          this.web3.eth.getBlockNumber(),
          this.web3.eth.getGasPrice()
        ]);

        this.blockNumber = blockNumber;
        this.gasPrice = gasPrice;
      } catch (error) {
        this.$message.error('区块数据获取失败: ' + error.message);
        console.error('区块数据错误:', error);
      } finally {
        this.loading.block = false;
      }
    },

    // 刷新区块数据
    async refreshBlockData() {
      await this.checkNodeConnection();
      await this.getBlockData();
      await this.getTotalTransactions()
    },

    // 地址格式化
    formatAddress(address) {
      return address ? `${address.slice(0, 6)}...${address.slice(-4)}` : '';
    },

    // Gas价格格式化
    formatGasPrice(wei) {
      return this.web3 ? Number(this.web3.utils.fromWei(wei, 'gwei')).toFixed(2) : '0.00';
    }
  },

  async mounted() {
    await this.initWeb3();
    // 每15秒自动更新区块数据
    this.autoUpdate = setInterval(this.getBlockData, 15000);
  },

  beforeDestroy() {
    clearInterval(this.autoUpdate);
  }
};
</script>

<style scoped lang="scss">
.container {
  max-width: 1200px;
  margin: 0 auto;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}
.clearfix:after {
  clear: both;
}

.address-text {
  cursor: pointer;
  font-family: monospace;
  color: #409EFF;
  &:hover {
    text-decoration: underline;
  }
}

.el-card {
  margin-bottom: 20px;
  transition: box-shadow 0.3s;

  &:hover {
    box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
  }
}

.block-info {
  padding: 10px;
  .info-item {
    margin: 12px 0;
    label {
      display: inline-block;
      width: 120px;
      text-align: right;
      margin-right: 15px;
    }
    .el-tag {
      min-width: 100px;
      text-align: center;
    }
  }
}

.el-tag {
  font-weight: bold;
  letter-spacing: 0.5px;
}
</style>
